/*
 * Listener.java
 * This file is a basic server-side application, which communicate with the agent on connection info
 * and work collaboratively with client-side application
 * It receive a message from the client and reply with some additional header to the client
 * Simple as that...
 * It uses Delegator to faciliate the communication protocol with agent on connection start and destroy
 * The basic input argument.
 * -port $port(the port that app listens to) -monitorport $monitorport(the port of the agent)
 * 
 * */

package wps.servicebus.client;

import java.net.*;
import java.util.Random;
import java.io.*;

import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.log4j.Logger;

import wps.servicebus.Network;
import wps.servicebus.agent.AppProcess;

public class Listener{
	static Logger logger = Logger.getLogger(Listener.class);
	Delegator delegator = null;
	ServerSocket listener = null;
	Socket client = null;
	PrintWriter out = null;
	BufferedReader in = null;	
	
	public Listener(int port, int monitorPort){		
		try {
			logger.info("application started...");
			//initialize a delegator and use it to delegate all the start and destroy message with the agent
			delegator = new Delegator(port, monitorPort);
			listener = new ServerSocket(port);
			client = listener.accept();		
			
			//after connection established, send a success message using the delegator
			delegator.sendStartMessage(getProcessID());
			
			//write application as usual
			out = new PrintWriter(client.getOutputStream(), true);
			in = new BufferedReader(new InputStreamReader(client.getInputStream()));
			String input;
			while((input = in.readLine()) != null){								
				out.println("application on port " + listener.getLocalPort() + " received your message as below:");
				out.println(input);				
			}			
		} catch (IOException e) {
			delegator.sendDestroyMessage(getProcessID());
		} finally{	
			try{
				out.close();
				client.close();
				in.close();
				listener.close();			
			} catch (IOException e) {
				// TODO Auto-generated catch block				
			}
		}
	}
	private int getProcessID(){
		Random random = new Random();
		return Math.abs(random.nextInt() % 1000);
	}
	public static void main(String[] args) throws ParseException{	
		//parse the command line
		Options opt = new Options();

        opt.addOption("port", true, "port");    
        opt.addOption("monitorport", true, "monitor port");
        BasicParser parser = new BasicParser();
        CommandLine cl = parser.parse(opt, args);        
        System.out.println(cl.getOptionValue("port"));     
        
		new Listener(Integer.parseInt(cl.getOptionValue("port")), 
				Integer.parseInt(cl.getOptionValue("monitorport")));
	}
}
